//only record creep Behavior

const {EnumRole, EnumBehavior, EnumHarvestMode, EnumFlag, EnumReplenish} = require("./Enum");
const {findEnergyStore, findFlagList, findRoomFlagList, findBaseStore, findBestClose, findOutFlag, findRoleCreeps} = require("./Find");

/**
 * draw energy
 * @param creep
 */
module.exports.withDraw = creep => {
    if (creep.memory.replenishId) {
        creep.bestWithdraw(Game.getObjectById(creep.memory.replenishId))
        creep.finishReplenishId();
        return;
    }
    creep.finishReplenishId();
}

/**
 * TransOtherCreep
 * @param creep
 */
module.exports.carryOtherCreep = creep => {
    if (creep.memory.replenishId) {
        let otherCreep = Game.getObjectById(creep.memory.replenishId);
        if (otherCreep === null) {
            creep.finishReplenishId();
            return;
        }
        if (otherCreep.usedStore() === 0) {
            creep.finishReplenishId();
            return;
        }
        if (!creep.pos.isNearTo(otherCreep)) {
            creep.bestMove(otherCreep)
            otherCreep.bestMove(creep);
        } else {
            otherCreep.transfer(creep, RESOURCE_ENERGY);
            creep.finishReplenishId();
        }
    }
}

/**
 * trans to build
 * @param creep
 */
module.exports.replenishBuild = creep => {
    if (creep.memory.behaviorId) {
        let build = Game.getObjectById(creep.memory.behaviorId);
        let state = creep.bestTrans(build);
        if(build===null){
            creep.finishBehavior();
            return;
        }
        if(state===0&&(build.structureType===STRUCTURE_STORAGE||build.structureType===STRUCTURE_CONTAINER||build.structureType===STRUCTURE_TERMINAL)){
            creep.finishBehavior();
            return;
        }
        if (state === ERR_FULL) {
            creep.finishBehavior();
            return;
        }
        if (build.freeStore() === 0) {
            creep.finishBehavior();
        }
        return;
    }
    creep.finishBehavior();
}

/**
 * pick up energy
 * @param creep
 */
module.exports.pickUp = creep => {
    if (creep.memory.replenishId) {
        let relatedItem = Game.getObjectById(creep.memory.replenishId);
        if (relatedItem === null) {
            creep.finishReplenishId();
            return;
        }
        creep.bestPickup(relatedItem);
        if (creep.freeStore() === 0 || relatedItem.amount === 0) {
            creep.finishReplenishId();
        }
    }
}
/**
 * RepairBuild
 * @param creep
 */
module.exports.repair = creep => {
    if (creep.memory.behaviorId) {
        let behaviorId = Game.getObjectById(creep.memory.behaviorId);
        creep.bestRepair(behaviorId);

        if (creep.store.getUsedCapacity() === 0) {
            creep.finishReplenishId();
        }
        if(behaviorId.structureType===STRUCTURE_RAMPART&&behaviorId.hits > 30000 * creep.room.controller.level){
            creep.finishBehavior();
            return
        }
        if(behaviorId.structureType === STRUCTURE_WALL){
            if(creep.room.controller.level<3){
                creep.finishBehavior();
                return
            }
            if(behaviorId.isActive() && behaviorId.hits > 50000 * creep.room.controller.level){
                creep.finishBehavior();
            }
            return
        }
        if (behaviorId.hits === behaviorId.hitsMax) {
            creep.finishBehavior();
        }
    }
}

/**
 * UpController
 * @param creep
 */
module.exports.up = creep => {
    creep.bestUpController(creep.room.controller);
}

/**
 * Building
 * @param creep
 * @returns {*}
 */
module.exports.build = creep => {
    if (creep.memory.behaviorId) {
        let behaviorId = Game.getObjectById(creep.memory.behaviorId);
        let state = creep.bestBuild(behaviorId);
        if (state === -7 || behaviorId === null || behaviorId.progress === behaviorId.progressTotal) {
            creep.finishBehavior();
            return;
        }
        //身上没有能量
        if (creep.store.getUsedCapacity() === 0) {
            creep.finishReplenishId();
        }
    }else{
        creep.finishReplenishId();
    }
}

/**
 * TransMineral
 * @param creep
 */
module.exports.transMineral = creep => {
    let haveOther;
    for (let storeKey in creep.store) {
        if (creep.usedStore(storeKey) > 0) {
            haveOther = true;
            break;
        }
    }
    let behaviorId;
    if (creep.memory.replenishId && haveOther) {
        behaviorId = Game.getObjectById(creep.memory.behaviorId);
        creep.bestTrans(behaviorId, haveOther)
    }
    //if store is empty or StoreBuild is not free store
    if (creep.freeStore() === 0 || behaviorId.freeStore() === 0) {
        creep.finishBehavior();
    }
}

module.exports.getPixel = () => {
    if (Game.time % 100 === 0 && Game.cpu.bucket >= 10000) {
        Game.cpu.generatePixel();
        console.log('Get One Pixel！');
    }
}

//public
module.exports.replenishEnergy = (creep) => {
    //priority close energy
    let roomCreepList = creep.room.find(FIND_MY_CREEPS);
    let behaviorType=null;
    try {
        behaviorType = Game.getObjectById(creep.memory.behaviorId).structureType;
        if(behaviorType===STRUCTURE_STORAGE||behaviorType===STRUCTURE_CONTAINER){
            if(creep.room.find(FIND_DROPPED_RESOURCES,{filter:resource=>resource.amount>100}).length===0){
                creep.finishBehavior();
                return;
            }
        }
    } catch (e) {}
    if(creep.memory.role===EnumRole.Engineer&&creep.room.memory.upLink){
        let link=Game.getObjectById(creep.room.memory.upLink);
        if(link!==null&&creep.pos.findInRange([link],3).length>0&&link.usedStore()>0){
            creep.bindReplenish(EnumReplenish.ReplenishEnergy,link.id);
            return;
        }
    }
    if(creep.memory.role!==EnumRole.Butler||behaviorType===STRUCTURE_TOWER||behaviorType===STRUCTURE_EXTENSION||behaviorType===STRUCTURE_SPAWN){//急需优化
        let fullStoreList = findEnergyStore(creep.room).filter(store => store.usedStore() > 0);
        let enableEnergy = 0;
        for (let store of fullStoreList) {
            enableEnergy += store.usedStore();
        }
        //filter is bind store
        fullStoreList = fullStoreList.filter(store => {
            let maxBind = 1;
            let bindSize = 0;
            if(store.usedStore()===store.maxStore()||store.usedStore() > 5000){
                return true;
            }
            if (store.usedStore() > 1000) {
                maxBind = 3
            } else if (store.usedStore() > 500) {
                maxBind = 2
            }
            for (let creepItem of roomCreepList) {
                if (creepItem.memory.replenishId === store.id) {
                    bindSize++;
                }
            }
            return bindSize < maxBind;
        })
        if (fullStoreList.length > 0) {
            creep.memory.replenish = EnumReplenish.ReplenishEnergy;
            creep.memory.replenishId = findBestClose(creep, fullStoreList);
            return;
        }
    }
    //get full butler energy
    if(creep.memory.role !== EnumRole.Butler){
        let freeFullButlerList = findRoleCreeps(EnumRole.Butler,creep.room).filter(creep=>{
            return creep.memory.isBehavior===false&&creep.memory.replenish===EnumReplenish.Free&&creep.usedStore()>0
        })
        let findInRangeList = creep.pos.findInRange(freeFullButlerList,10);
        if(findInRangeList.length>0){
            creep.bindReplenish(EnumReplenish.WithDrawOtherCreep,findInRangeList[0].id);
            return;
        }
    }
    //dropResourceList
    let dropResourceList = creep.room.find(FIND_DROPPED_RESOURCES).filter(resource => {
        if (resource.amount < 20) {
            return false;
        }
        if(resource.resourceType!==RESOURCE_ENERGY&&(creep.room.storage===undefined||creep.room.storage.my===false)){
            return false;
        }
        let maxBind = 1;
        let bindSize = 0
        if (resource.amount > 3000){
            return true
        }else if (resource.amount>1000){
            maxBind=3
        }else if(resource.amount>500){
            maxBind=2
        }
        for (let creepItem of roomCreepList) {
            if (creepItem.memory.replenishId === resource.id) {
                bindSize++;
            }
        }
        return bindSize < maxBind;
    });
    if (dropResourceList.length > 0) {
        creep.memory.replenish = EnumReplenish.PickEnergy;
        creep.memory.replenishId = findBestClose(creep, dropResourceList);
        return;
    }

}

//attackCreep
module.exports.attackCreep = creep => {
    let relateItem = Game.getObjectById(creep.memory.replenishId);
    let state = creep.attack(relateItem);
    if (state === ERR_NOT_IN_RANGE) {
        creep.bestMove(relateItem)
    }
    if (relateItem === undefined || state === -7) {
        creep.memory.behavior = EnumBehavior.Free;
        creep.memory.replenishId = undefined;
    }
}

//outCreep behavior
module.exports.followFlagUpRoom = creep => {
    //priority find upRoomTo
    let upRootFlagTo = findFlagList(EnumFlag.UpRootTo,1);
    if (upRootFlagTo) {
        if (creep.pos.findInRange([upRootFlagTo],2).length>0) {
            creep.memory.workRoom = creep.room.name;
            return;
        }
        creep.bestMove(upRootFlagTo.pos);
        return;
    }
    //is not,find upRoom
    let upRootFlag = findFlagList(EnumFlag.UpRoot, 1);
    if (upRootFlag) {
        creep.bestMove(upRootFlag.pos);
    }
}

//move to stop position
module.exports.toStop=creep=>{
    let stopList = findRoomFlagList(creep.room,EnumFlag.Stop);
    if(stopList.length>0&&!stopList[0].pos.inRangeTo(creep,2)){
        creep.bestMove(stopList[0])
    }
}